package com.efast.dmom.mgmt.service.les.impl;

import com.efast.cafe.framework.exception.ServiceException;
import com.efast.dmom.mgmt.dao.les.*;
import com.efast.dmom.mgmt.entity.les.*;
import com.efast.dmom.mgmt.service.les.TwOutbTaskHeaderService;
import com.efast.dmom.mgmt.service.mes.TwBasLotService;
import com.efast.dmom.mgmt.utils.Assist;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author chlp
 */
@Service
public class TwOutbTaskHeaderServiceImpl implements TwOutbTaskHeaderService {

	/**
	 * 出库订单表TW_DOC_ORDER_HEADER
	 */
	private final TwDocOrderHeaderDao twDocOrderHeaderDao;
	/**
	 * 出库订单表 TW_DOC_ORDER_DETAILS
	 */
	private final TwDocOrderDetailsDao twDocOrderDetailsDao;
	/**
	 * 拣货任务表 TW_OUTB_TASK_HEADER
	 */
	private final TwOutbTaskHeaderDao twOutbTaskHeaderDao;
	/**
	 * 拣货任务表 TW_OUTB_TASK_DETAIL
	 */
	private final TwOutbTaskDetailDao twOutbTaskDetailDao;
	/**
	 * 库存表TW_INV_SKU_LOC_T_L
	 */
	private final TwInvSkuLoctlDao twInvSkuLoctlDao;
	private final TwBasLotService twBasLotService;

	@Autowired
	public TwOutbTaskHeaderServiceImpl(TwDocOrderHeaderDao twDocOrderHeaderDao,
			TwDocOrderDetailsDao twDocOrderDetailsDao, TwOutbTaskHeaderDao twOutbTaskHeaderDao,
			TwOutbTaskDetailDao twOutbTaskDetailDao, TwInvSkuLoctlDao twInvSkuLoctlDao,
			TwBasLotService twBasLotService) {
		this.twDocOrderHeaderDao = twDocOrderHeaderDao;
		this.twDocOrderDetailsDao = twDocOrderDetailsDao;
		this.twOutbTaskHeaderDao = twOutbTaskHeaderDao;
		this.twOutbTaskDetailDao = twOutbTaskDetailDao;
		this.twInvSkuLoctlDao = twInvSkuLoctlDao;
		this.twBasLotService = twBasLotService;
	}

	/**
	 * 确认捡货：更新header和detail状态。只能整单确认。 及时到的表： a) 拣货任务表 TW_OUTB_TASK_HEADER、TW_OUTB_TASK_DETAIL b) 分配表 TW_ACT_ALLOC_LOT_D
	 * c) 出库订单表TW_DOC_ORDER_HEADER、TW_DOC_ORDER_DETAILS d) 库存表TW_INV_SKU_LOC_T_L
	 * 
	 * @param twOutbTaskHeader
	 *            twOutbTaskHeader
	 */
	@Override
	public void confirmPicking(TwOutbTaskHeader twOutbTaskHeader) {

		List<TwOutbTaskDetail> listTwOutbTaskDetail = twOutbTaskDetailDao.selectTwOutbTaskDetail(new Assist(
				Assist.andEq("tw_outb_task_detail.tw_outb_task_header_id", twOutbTaskHeader.getTwOutbTaskHeaderId())));

		// 【1】：更新 拣货任务表 TW_OUTB_TASK_HEADER的状态-->拣货完成
		// 拣货状态 : 0新任务,1拣货完成,2部分拣货 3关闭
		twOutbTaskHeader.setInboundStatus("1");
		twOutbTaskHeaderDao.updateNonEmptyTwOutbTaskHeaderById(twOutbTaskHeader);

		// 【2】：出库订单表TW_DOC_ORDER_HEADER
		TwDocOrderHeader twDocOrderHeader = new TwDocOrderHeader();
		// SO单证状态（新单0、部分分配1、分配完成2、部分拣货3、拣货完成4、部分装箱5、装箱完成6、部分发运7、发运完成8、订单取消9、单证关闭10）
		twDocOrderHeader.setSoSheetStatus("4");
		twDocOrderHeaderDao.updateNonEmptyTwDocOrderHeader(twDocOrderHeader,
				new Assist(Assist.andEq("tw_doc_order_header.so_sheet_no", twOutbTaskHeader.getSoSheetNo())));
		// 【3】：遍历 拣货任务表 TW_OUTB_TASK_DETAIL
		for (TwOutbTaskDetail twOutbTaskDetail : listTwOutbTaskDetail) {
			// 【4】：更新TW_OUTB_TASK_DETAIL【拣货任务表】的状态-->拣货完成
			TwOutbTaskDetail enti = new TwOutbTaskDetail();
			enti.setTwOutbTaskDetailId(twOutbTaskDetail.getTwOutbTaskDetailId());
			enti.setActTmBasStorageId(twOutbTaskDetail.getPreTmBasStorageId());
			// 拣货状态（新任务0，任务完成1，2部分拣货）
			enti.setPickStatus("1");
			// 实际拣货数量 --》 实际分配数量
			enti.setActPickQty(twOutbTaskDetail.getAllocQty());
			// 实际拣货库内跟踪流水号码 --》库内跟踪流水号码
			enti.setActPickInbSerialNo(twOutbTaskDetail.getInbSerialNo());
			// 实际拣货零件包装流水号--》零件包装流水号
			enti.setActPickPartPackSerial(twOutbTaskDetail.getPartPackSerial());
			twOutbTaskDetailDao.updateNonEmptyTwOutbTaskDetailById(enti);

			// 【5】：更新TW_DOC_ORDER_DETAILS【出库订单表】的状态-->拣货完成
			TwDocOrderDetails twDocOrderDetails = new TwDocOrderDetails();
			// 订单行状态（新单0、部分分配1、分配完成2、部分拣货3、拣货完成4、订单取消9、关闭10、分配失败11）
			twDocOrderDetails.setLineStatus("4");
			// 实际拣货数量-->实际分配数量
			twDocOrderDetails.setPickAllocQty(twOutbTaskDetail.getAllocQty());
			// 实际拣货包装代码
			twDocOrderDetails.setPickAllocPack(twOutbTaskDetail.getPreAllocPack());
			// 实际拣货包装数
			twDocOrderDetails.setPickAllocPackNum(twOutbTaskDetail.getPreAllocPackNum());
			twDocOrderDetailsDao.updateNonEmptyTwDocOrderDetails(twDocOrderDetails,
					new Assist(Assist.andEq("tw_doc_order_details.so_lineno", twOutbTaskDetail.getSoLineno()),
							Assist.andEq("tw_doc_order_details.so_sheet_no", twOutbTaskDetail.getSoSheetNo())));

			// 【6】：更新 库存表TW_INV_SKU_LOC_T_L
			// 分配完成后的库存变化 ： 可用数量-AVAILABLE_QTY==0 , 库存数量-CUR_QTY==0 , 待出库数量-R_OUB_QTY==1
			// 分配数量-R_ALLOC_QTY == 0 , 出库订单分配数量-SO_R_ALLOC_QTY == 0 , 拣货数量-R_PICK_QTY == 1
			// 出库订单拣货数量-SO_R_PICK_QTY == 1
			List<TwInvSkuLoctl> listTwInvSkuLoctl = twInvSkuLoctlDao.selectTwInvSkuLoctl(
					new Assist(Assist.andEq("tw_inv_sku_loc_t_l.tm_bas_storage_id", twOutbTaskDetail.getDestLocId()),
							Assist.andEq("tw_inv_sku_loc_t_l.part_no_version", twOutbTaskDetail.getPartNoVersion())));
			TwInvSkuLoctl twInvSkuLoctl = listTwInvSkuLoctl.get(0);
			// 库存数量-CUR_QTY
			twInvSkuLoctl.setCurQty(twInvSkuLoctl.getCurQty() - twOutbTaskDetail.getAllocQty());
			// 分配数量-R_ALLOC_QTY
			twInvSkuLoctl.setrAllocQty(twInvSkuLoctl.getrAllocQty() - twOutbTaskDetail.getAllocQty());
			// 出库订单分配数量-SO_R_ALLOC_QTY
			twInvSkuLoctl.setSorAllocQty(twInvSkuLoctl.getSorAllocQty() - twOutbTaskDetail.getAllocQty());
			// 拣货数量-R_PICK_QTY 实际拣货数量 ，目前不让编辑 -ActPickQty()
			twInvSkuLoctl.setrPickQty(twOutbTaskDetail.getAllocQty());
			// 出库订单拣货数量-SO_R_PICK_QTY
			twInvSkuLoctl.setSorPickQty(twOutbTaskDetail.getAllocQty());
			twInvSkuLoctlDao.updateNonEmptyTwInvSkuLoctlById(twInvSkuLoctl);
			// 打印拣货任务单
			List<TwDocOrderHeader> header = twDocOrderHeaderDao.selectTwDocOrderHeader(
					new Assist(Assist.andEq("tw_doc_order_header.so_sheet_no", twOutbTaskHeader.getSoSheetNo())));
			twBasLotService.printPickCard(listTwOutbTaskDetail,
					header != null && header.size() > 0 ? header.get(0).getCustSheetId() : "");
		}

	}

	/**
	 * 确认捡货【针对pda明细拣货，可以修改拣货数量的情况】：更新header和detail状态。只能整单确认。
	 *
	 * 更新header和detail状态。只能整单确认。 及时到的表：
	 *
	 * a) 拣货任务表 TW_OUTB_TASK_HEADER、TW_OUTB_TASK_DETAIL
	 *
	 * b) 分配表 TW_ACT_ALLOC_LOT_D
	 *
	 * c) 出库订单表TW_DOC_ORDER_HEADER、TW_DOC_ORDER_DETAILS
	 * 
	 * d) 库存表TW_INV_SKU_LOC_T_L
	 *
	 * @param reqListTwOutbTaskDetail
	 *            reqListTwOutbTaskDetail
	 */
	@Override
	public void confirmPickingEdit(List<TwOutbTaskDetail> reqListTwOutbTaskDetail) {

		TwOutbTaskHeader twOutbTaskHeader = new TwOutbTaskHeader();
		twOutbTaskHeader.setTwOutbTaskHeaderId(reqListTwOutbTaskDetail.get(0).getTwOutbTaskHeaderId());
		twOutbTaskHeader.setSoSheetNo(reqListTwOutbTaskDetail.get(0).getSoSheetNo());
		// 前端传递来的明细，可能实际拣货数量会被修改
		// 数据库查询出来的明细数据
		List<TwOutbTaskDetail> listTwOutbTaskDetail = twOutbTaskDetailDao.selectTwOutbTaskDetail(new Assist(
				Assist.andEq("tw_outb_task_detail.tw_outb_task_header_id", twOutbTaskHeader.getTwOutbTaskHeaderId())));

		// 【1】：更新 拣货任务表 TW_OUTB_TASK_HEADER的状态-->拣货完成
		// 拣货状态 : 0新任务,1拣货完成,2部分拣货 3关闭
		twOutbTaskHeader.setInboundStatus("1");
		twOutbTaskHeaderDao.updateNonEmptyTwOutbTaskHeaderById(twOutbTaskHeader);

		// 【2】：出库订单表TW_DOC_ORDER_HEADER
		TwDocOrderHeader twDocOrderHeader = new TwDocOrderHeader();
		// SO单证状态（新单0、部分分配1、分配完成2、部分拣货3、拣货完成4、部分装箱5、装箱完成6、部分发运7、发运完成8、订单取消9、单证关闭10）
		twDocOrderHeader.setSoSheetStatus("4");
		twDocOrderHeaderDao.updateNonEmptyTwDocOrderHeader(twDocOrderHeader,
				new Assist(Assist.andEq("tw_doc_order_header.so_sheet_no", twOutbTaskHeader.getSoSheetNo())));
		// 【3】：遍历(用户传递过来的拣货明细) 拣货任务表 TW_OUTB_TASK_DETAIL
		for (TwOutbTaskDetail reqTtwOutbTaskDetail : reqListTwOutbTaskDetail) {

			// 数据库查询出来的detail
			TwOutbTaskDetail twOutbTaskDetail = null;
			for (TwOutbTaskDetail dbTwOutbTaskDetail1 : listTwOutbTaskDetail) {
				if (dbTwOutbTaskDetail1.getTwOutbTaskDetailId().equals(reqTtwOutbTaskDetail.getTwOutbTaskDetailId())) {
					twOutbTaskDetail = dbTwOutbTaskDetail1;
					break;
				}
			}
			if (twOutbTaskDetail == null) {
				throw new ServiceException("");
			}

			// 【4】：更新TW_OUTB_TASK_DETAIL【拣货任务表】的状态-->拣货完成
			TwOutbTaskDetail enti = new TwOutbTaskDetail();
			enti.setTwOutbTaskDetailId(twOutbTaskDetail.getTwOutbTaskDetailId());
			enti.setActTmBasStorageId(reqTtwOutbTaskDetail.getActTmBasStorageId());
			// 拣货状态（新任务0，任务完成1，2部分拣货）
			enti.setPickStatus("1");
			// 实际拣货数量 --》 用户输入的数量
			enti.setActPickQty(reqTtwOutbTaskDetail.getActPickQty());
			// 实际拣货库内跟踪流水号码 --》库内跟踪流水号码
			enti.setActPickInbSerialNo(reqTtwOutbTaskDetail.getInbSerialNo());
			// 实际拣货零件包装流水号--》零件包装流水号
			enti.setActPickPartPackSerial(reqTtwOutbTaskDetail.getPartPackSerial());
			twOutbTaskDetailDao.updateNonEmptyTwOutbTaskDetailById(enti);

			// 【5】：更新TW_DOC_ORDER_DETAILS【出库订单表】的状态-->拣货完成
			TwDocOrderDetails twDocOrderDetails = new TwDocOrderDetails();
			// 订单行状态（新单0、部分分配1、分配完成2、部分拣货3、拣货完成4、订单取消9、关闭10、分配失败11）
			twDocOrderDetails.setLineStatus("4");
			// 实际拣货数量-->实际分配数量
			twDocOrderDetails.setPickAllocQty(reqTtwOutbTaskDetail.getAllocQty());
			// 实际拣货包装代码
			twDocOrderDetails.setPickAllocPack(twOutbTaskDetail.getPreAllocPack());
			// 实际拣货包装数
			twDocOrderDetails.setPickAllocPackNum(twOutbTaskDetail.getPreAllocPackNum());
			twDocOrderDetailsDao.updateNonEmptyTwDocOrderDetails(twDocOrderDetails,
					new Assist(Assist.andEq("tw_doc_order_details.so_lineno", twOutbTaskDetail.getSoLineno()),
							Assist.andEq("tw_doc_order_details.so_sheet_no", twOutbTaskDetail.getSoSheetNo())));

			// 【6】：更新 库存表TW_INV_SKU_LOC_T_L
			// 分配完成后的库存变化 ： 可用数量-AVAILABLE_QTY==0 , 库存数量-CUR_QTY==0 , 待出库数量-R_OUB_QTY==1
			// 分配数量-R_ALLOC_QTY == 0 , 出库订单分配数量-SO_R_ALLOC_QTY == 0 , 拣货数量-R_PICK_QTY == 1
			// 出库订单拣货数量-SO_R_PICK_QTY == 1
			List<TwInvSkuLoctl> listTwInvSkuLoctl = twInvSkuLoctlDao.selectTwInvSkuLoctl(
					new Assist(Assist.andEq("tw_inv_sku_loc_t_l.tm_bas_storage_id", twOutbTaskDetail.getDestLocId()),
							Assist.andEq("tw_inv_sku_loc_t_l.part_no_version", twOutbTaskDetail.getPartNoVersion())));
			TwInvSkuLoctl twInvSkuLoctl = listTwInvSkuLoctl.get(0);
			// 库存数量-CUR_QTY
			twInvSkuLoctl.setCurQty(twInvSkuLoctl.getCurQty() - twOutbTaskDetail.getAllocQty());
			// 分配数量-R_ALLOC_QTY
			twInvSkuLoctl.setrAllocQty(twInvSkuLoctl.getrAllocQty() - twOutbTaskDetail.getAllocQty());
			// 出库订单分配数量-SO_R_ALLOC_QTY
			twInvSkuLoctl.setSorAllocQty(twInvSkuLoctl.getSorAllocQty() - twOutbTaskDetail.getAllocQty());
			// 拣货数量-R_PICK_QTY 实际拣货数量 ，目前不让编辑 -ActPickQty()
			twInvSkuLoctl.setrPickQty(reqTtwOutbTaskDetail.getAllocQty());
			// 出库订单拣货数量-SO_R_PICK_QTY
			twInvSkuLoctl.setSorPickQty(reqTtwOutbTaskDetail.getAllocQty());
			twInvSkuLoctlDao.updateNonEmptyTwInvSkuLoctlById(twInvSkuLoctl);
			// 打印拣货任务单
			List<TwDocOrderHeader> header = twDocOrderHeaderDao.selectTwDocOrderHeader(
					new Assist(Assist.andEq("tw_doc_order_header.so_sheet_no", twOutbTaskHeader.getSoSheetNo())));
			twBasLotService.printPickCard(listTwOutbTaskDetail,
					header != null && header.size() > 0 ? header.get(0).getCustSheetId() : "");
		}

	}

	/**
	 * 取消捡货：更新header和detail状态。只能整单取消。
	 * 
	 * @param enti
	 *            enti
	 */
	@Override
	public int cancelPicking(TwOutbTaskHeader enti) {
		TwOutbTaskDetail twOutbTaskDetail = new TwOutbTaskDetail();
		twOutbTaskDetail.setTwOutbTaskHeaderId(enti.getTwOutbTaskHeaderId());
		// 拣货状态（新任务0，任务完成1，2部分拣货）
		twOutbTaskDetail.setPickStatus("0");
		twOutbTaskDetailDao.updateNonEmptyTwOutbTaskDetail(twOutbTaskDetail,
				new Assist(Assist.andEq("tw_outb_task_detail.tw_outb_task_header_id", enti.getTwOutbTaskHeaderId())));
		TwOutbTaskHeader twOutbTaskHeader = new TwOutbTaskHeader();
		twOutbTaskHeader.setTwOutbTaskHeaderId(enti.getTwOutbTaskHeaderId());
		// 拣货状态0新任务1拣货完成2部分拣货3关闭
		twOutbTaskHeader.setInboundStatus("0");
		return twOutbTaskHeaderDao.updateNonEmptyTwOutbTaskHeaderById(twOutbTaskHeader);
	}

	@Override
	public long getTwOutbTaskHeaderRowCount(Assist assist) {
		return twOutbTaskHeaderDao.getTwOutbTaskHeaderRowCount(assist);
	}

	@Override
	public List<TwOutbTaskHeader> selectTwOutbTaskHeader(Assist assist) {
		return twOutbTaskHeaderDao.selectTwOutbTaskHeader(assist);
	}

	@Override
	public TwOutbTaskHeader selectTwOutbTaskHeaderByObj(TwOutbTaskHeader obj) {
		return twOutbTaskHeaderDao.selectTwOutbTaskHeaderByObj(obj);
	}

	@Override
	public TwOutbTaskHeader selectTwOutbTaskHeaderById(Integer id) {
		return twOutbTaskHeaderDao.selectTwOutbTaskHeaderById(id);
	}

	@Override
	public int insertTwOutbTaskHeader(TwOutbTaskHeader value) {
		return twOutbTaskHeaderDao.insertTwOutbTaskHeader(value);
	}

	@Override
	public int insertNonEmptyTwOutbTaskHeader(TwOutbTaskHeader value) {
		return twOutbTaskHeaderDao.insertNonEmptyTwOutbTaskHeader(value);
	}

	@Override
	public int insertTwOutbTaskHeaderByBatch(List<TwOutbTaskHeader> value) {
		return twOutbTaskHeaderDao.insertTwOutbTaskHeaderByBatch(value);
	}

	@Override
	public int deleteTwOutbTaskHeaderById(Integer id) {
		return twOutbTaskHeaderDao.deleteTwOutbTaskHeaderById(id);
	}

	@Override
	public int deleteTwOutbTaskHeader(Assist assist) {
		return twOutbTaskHeaderDao.deleteTwOutbTaskHeader(assist);
	}

	@Override
	public int updateTwOutbTaskHeader(TwOutbTaskHeader value, Assist assist) {
		return twOutbTaskHeaderDao.updateTwOutbTaskHeader(value, assist);
	}

	@Override
	public int updateNonEmptyTwOutbTaskHeaderById(TwOutbTaskHeader enti) {
		return twOutbTaskHeaderDao.updateNonEmptyTwOutbTaskHeaderById(enti);
	}

	@Override
	public int updateNonEmptyTwOutbTaskHeader(TwOutbTaskHeader value, Assist assist) {
		return twOutbTaskHeaderDao.updateNonEmptyTwOutbTaskHeader(value, assist);
	}

	@Override
	public int updateTwOutbTaskHeaderById(TwOutbTaskHeader enti) {
		return 0;
	}

}